package com.tundriki.pref;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLU;
import android.opengl.Matrix;


public class gameTableRenderer  implements android.opengl.GLSurfaceView.Renderer {
	private final Context context;
	private TextureBundle tex=null;
	private GameClient client;
	private int[] viewPort = new int[4];
	private float[] _finalMatrix = new float[16],
					_tmpVect = new float[4];
	private float[][] _eventCoord = new float[2][4];
	private MyGLSurface view;
	private MatrixGrabber mg;
	
	
	public gameTableRenderer(Context context, MyGLSurface view) {
		super();
		this.context = context;
		this.view = view;
		mg = new MatrixGrabber();
	}
	/*
	private FloatBuffer normLine() {
		FloatBuffer b=TextureBundle.createBuffer(6);
		float[] t = {0,0,0};
		float kx = 0, ky = 0;
		b.position(0);
		kx = (_eventCoord[1][0]-_eventCoord[0][0])/(_eventCoord[1][2]-_eventCoord[0][2]);
		ky = (_eventCoord[1][1]-_eventCoord[0][1])/(_eventCoord[1][2]-_eventCoord[0][2]);
		
		t[0] = _eventCoord[0][0] + kx*(-0.1f - _eventCoord[0][2]);
		t[1] = _eventCoord[0][1] + ky*(-0.1f - _eventCoord[0][2]);
		t[2] = -0.1f;
		b.put(t);
		t[0] = _eventCoord[0][0] + kx*(0.8f - _eventCoord[0][2]);
		t[1] = _eventCoord[0][1] + ky*(0.8f - _eventCoord[0][2]);
		t[2] = 0.8f;
		b.put(t);
		return b;
	}*/

	/*private void drawDbgLine(GL10 gl) {
		FloatBuffer buf=normLine();
		buf.position(0);
		
//	    gl.glFrontFace(GL10.GL_CCW);
	    gl.glEnable(GL10.GL_CULL_FACE);
	    gl.glCullFace(GL10.GL_BACK);

	    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		
		//gl.glDepthMask(false);
		gl.glColor4f(1.0f, 0.8f, 0.0f, 1f);
		gl.glLineWidth(5f);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, buf);
		gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, 2);
		
		
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisable(GL10.GL_CULL_FACE);

		
		//gl.glDepthMask(true);
	}*/

	public void onDrawFrame(GL10 gl) {
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        gl.glLoadIdentity();
        gl.glTranslatef(0.0f, 0.0f, -3f);
        client.draw(gl);
        if (view.what!=GameClient.NONE) {
        	float wX = view.x, wY=view.y;
        	
       		if (unProject(wX,wY)) {
       			//drawDbgLine(gl);
       			client.onActionEvent(_eventCoord, view.what);
       		}
       		view.what = GameClient.NONE;
        }
	}

	public void onSurfaceChanged(GL10 gl, int width, int height) {
		/* code from tutorial */
        // make adjustments for screen ratio
		
		if (height == 0)
			height = 1;
		
		float ratio = (float) width / height;
		
		viewPort[2] = width;
		viewPort[3] = height;
				
		mg.getCurrentProjection(gl);
		mg.getCurrentModelView(gl);
		
		gl.glViewport(0, 0, width, height);		
		gl.glMatrixMode(GL10.GL_PROJECTION);        // set matrix to projection mode
		gl.glLoadIdentity();                        // reset the matrix to its default state
		GLU.gluPerspective(gl, 45.0f, ratio, 0.1f, 100.0f);
	    
		gl.glMatrixMode(GL10.GL_MODELVIEW);     //Select The Modelview Matrix
		gl.glLoadIdentity();                    //Reset The Modelview Matrix
	
	}
	
	public void onSurfaceCreated(GL10 gl, EGLConfig cfg) {
		tex = new TextureBundle(gl, context);
		
		client = new GameClient(tex);
		
		gl.glEnable(GL10.GL_TEXTURE_2D);			//Enable Texture Mapping ( NEW )
		gl.glShadeModel(GL10.GL_SMOOTH); 			//Enable Smooth Shading
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); 	//Black Background
		gl.glClearDepthf(1.0f); 					//Depth Buffer Setup
		gl.glEnable(GL10.GL_DEPTH_TEST); 			//Enables Depth Testing
		gl.glDepthFunc(GL10.GL_LEQUAL); 			//The Type Of Depth Testing To Do
		
		gl.glEnable(GL10.GL_LINE_SMOOTH);
		
		viewPort[0] = viewPort[1] = 0;
		viewPort[2] = view.getWidth();
		viewPort[3] = view.getHeight();
		mg.getCurrentProjection(gl);
		mg.getCurrentModelView(gl);
		
		//Really Nice Perspective Calculations
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); 
		
	}
	
	private boolean unProject(float winx, float winy) {
		Matrix.multiplyMM(_finalMatrix, 0, mg.mProjection, 0, mg.mModelView, 0);
		if (!Matrix.invertM(_finalMatrix, 0, _finalMatrix, 0))
			return false;
		winy = viewPort[3]-viewPort[1]-winy;
		_tmpVect[0] = 2*(winx - viewPort[0])/viewPort[2]-1;
		_tmpVect[1] = 2*(winy - viewPort[1])/viewPort[3]-1;
		_tmpVect[2] = 0;
		_tmpVect[3] = 1.0f;

		// Map x and y from window coordinates

		Matrix.multiplyMV(_eventCoord[0], 0, _finalMatrix, 0, _tmpVect, 0);
				
		if (_tmpVect[3] == 0.0f)
			return false;
				
		/*_eventCoord[0][0] /= _eventCoord[0][3]; 
		_eventCoord[0][1] /= _eventCoord[0][3]; 
		_eventCoord[0][2] /= _eventCoord[0][3];
		_eventCoord[0][3] = 1f; */ 

		_tmpVect[2] = 1f;
		Matrix.multiplyMV(_eventCoord[1], 0, _finalMatrix, 0, _tmpVect, 0);
		if (_tmpVect[3] == 0.0f)
			return false;
				
		/*_eventCoord[1][0] /= _eventCoord[1][3]; 
		_eventCoord[1][1] /= _eventCoord[1][3]; 
		_eventCoord[1][2] /= _eventCoord[1][3];
		_eventCoord[0][3] = 1f;*/ 

		return true;
}

}